package com.ruoyi.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.websocket.WebSocketServer;
import com.ruoyi.domain.*;
import com.ruoyi.dto.WeChatTemplateMsg;
import com.ruoyi.mapper.JkPushMapper;
import com.ruoyi.service.*;
import com.ruoyi.utils.WeChatUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 推送管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-09-12
 */
@Service
public class JkPushServiceImpl extends ServiceImpl<JkPushMapper,JkPush> implements IJkPushService
{
    private static final Logger log = LoggerFactory.getLogger(JkPushServiceImpl.class);

    @Autowired
    private JkPushMapper jkPushMapper;

    @Autowired
    private IJkPushUserService pushUserService;

    @Autowired
    private IJkGroupUserService groupUserService;

    @Autowired
    private IJkUserService userService;

    @Autowired
    private WebSocketServer webSocketServer;

    @Value("${wechat.appId}")
    private String appId;

    @Value("${wechat.appSecret}")
    private String appSecret;

    @Value("${wechat.templateId}")
    private String templateId;

    @Autowired
    private WeChatUtil weChatUtil;

    @Autowired
    private IJkFllowupService fllowupService;

    @Autowired
    private IJkFllowupMessageService messageService;

    /**
     * 查询推送管理
     *
     * @param id 推送管理主键
     * @return 推送管理
     */
    @Override
    public JkPush selectJkPushById(Long id)
    {
        return jkPushMapper.selectJkPushById(id);
    }

    /**
     * 查询推送管理列表
     *
     * @param jkPush 推送管理
     * @return 推送管理
     */
    @Override
    public List<JkPush> selectJkPushList(JkPush jkPush)
    {
        return jkPushMapper.selectJkPushList(jkPush);
    }

    /**
     * 新增推送管理
     *
     * @param jkPush 推送管理
     * @return 结果
     */
    @Override
    public int insertJkPush(JkPush jkPush)
    {
        jkPush.setCreateTime(DateUtils.getNowDate());
        return jkPushMapper.insertJkPush(jkPush);
    }

    /**
     * 修改推送管理
     *
     * @param jkPush 推送管理
     * @return 结果
     */
    @Override
    public int updateJkPush(JkPush jkPush)
    {
        return jkPushMapper.updateJkPush(jkPush);
    }

    /**
     * 批量删除推送管理
     *
     * @param ids 需要删除的推送管理主键
     * @return 结果
     */
    @Override
    public int deleteJkPushByIds(Long[] ids)
    {
        return jkPushMapper.deleteJkPushByIds(ids);
    }

    /**
     * 删除推送管理信息
     *
     * @param id 推送管理主键
     * @return 结果
     */
    @Override
    public int deleteJkPushById(Long id)
    {
        return jkPushMapper.deleteJkPushById(id);
    }

    @Override
    @Transactional
    public void startJob() throws IOException {
        log.info("每日定时推送任务启动！日期为:"+DateUtils.getDate());
        JkPush jkPush = new JkPush();
        jkPush.setPushWay(1);//定时推送
        jkPush.setPushTime(DateUtils.getNowDate());
        List<JkPush> jkPushes = jkPushMapper.selectJkPushList(jkPush);
        ArrayList<Long> userIds = new ArrayList<>();
        jkPushes.forEach(push->{
            Integer pushModel = push.getPushModel();
            if(pushModel==1){
                JkPushUser jkPushUser = new JkPushUser();
                jkPushUser.setPushId(push.getId());
                List<JkPushUser> jkPushUsers = pushUserService.selectJkPushUserList(jkPushUser);
                jkPushUsers.forEach(pushUser->{
                    userIds.add(pushUser.getUserId());
                });
            }else{
                JkGroupUser jkGroupUser = new JkGroupUser();
                jkGroupUser.setGroupId(push.getGroupId());
                List<JkGroupUser> jkGroupUsers = groupUserService.selectJkGroupUserList(jkGroupUser);
                jkGroupUsers.forEach(groupUser -> {
                    userIds.add(groupUser.getUserId());
                });
            }
        });
        if(userIds.size()==0){
            log.info("当日无推送任务->"+DateUtils.getDate());
            return;
        }
        Map<String, String> openIdAndUnionIdMap = weChatUtil.getOpenIdAndUnionIdMap();
        String gzhToken = weChatUtil.getGzhToken();
        List<JkUser> jkUsers = userService.selectJkUserByIds(userIds);
        for(JkUser user:jkUsers){
            String unionId = user.getUnionId();
            if(unionId==null||StringUtils.isEmpty(unionId)){
                log.info("用户unionId为空");
                continue;
            }
            //创建随访
            JkFllowup jkFllowup = new JkFllowup();
            jkFllowup.setUserId(user.getId());
            jkFllowup.setCreateTime(DateUtils.getNowDate());
            fllowupService.insertJkFllowup(jkFllowup);

            String gzh_openId = openIdAndUnionIdMap.get(unionId);
            if(gzh_openId==null|| StringUtils.isEmpty(gzh_openId)){
                log.info("推送失败，未根据用户unionid："+unionId+"匹配到公众号openId");
            }else{
                //公众号推送
                sendMessage(gzh_openId,gzhToken,jkFllowup.getId(),1L);
                try {
                    JkFllowupMessage jkFllowupMessage = new JkFllowupMessage();
                    jkFllowupMessage.setFllowupId(jkFllowup.getId());
                    jkFllowupMessage.setUserId(user.getId());
                    jkFllowupMessage.setIfRead(0);
                    messageService.insertJkFllowupMessage(jkFllowupMessage);
                    webSocketServer.sendMessageTo("refresh",user.getId().toString());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    public void sendMessage(String openId, String accessToken, Long fllowupId, Long messageId) {
        Map<String, WeChatTemplateMsg> sendMag = new HashMap<String, WeChatTemplateMsg>();

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
        sendMag.put("thing5", new WeChatTemplateMsg("随访通知"));
        sendMag.put("time8", new WeChatTemplateMsg(DateUtils.getDate()));

        RestTemplate restTemplate = new RestTemplate();
        //拼接base参数
        Map<String, Object> sendBody = new HashMap<>();
        Map<String, Object> miniprogram = new HashMap<>();
        miniprogram.put("appid",appId);
        miniprogram.put("pagepath","pages/suifang/index?fllowupId="+fllowupId+"&messageId="+messageId);
        sendBody.put("touser", openId);               // openId
        sendBody.put("miniprogram",miniprogram);      //小程序数据
//        sendBody.put("url", "www.baidu.com");         // 点击模板信息跳转地址
        sendBody.put("topcolor", "#FF0000");          // 顶色
        sendBody.put("data", sendMag);                   // 模板参数
        sendBody.put("template_id", templateId);      // 模板Id
        ResponseEntity<String> forEntity = restTemplate.postForEntity(url, sendBody, String.class);
        log.info("结果是: "+forEntity.getBody());
        JSONObject jsonObject = JSONObject.parseObject(forEntity.getBody());
        String messageCode = jsonObject.getString("errcode");
        // 2431260672639467520
        String msgId = jsonObject.getString("msgid");
        log.info("messageCode : " + messageCode + ", msgId: " +msgId);
    }

    @Override
    public void pushMessageByGroupUser() {
        log.info("每日定时推送任务启动！日期为:"+DateUtils.getDate());
        JkPush jkPush = new JkPush();
        jkPush.setPushWay(1);//定时推送
        jkPush.setPushModel(2);//推送组推送
        List<JkPush> jkPushes = jkPushMapper.selectJkPushList(jkPush);
        Date nowDate = DateUtils.getNowDate();
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
        ArrayList<Long> userIds = new ArrayList<>();
        jkPushes.forEach(push->{
            String days = push.getDays();
            String format = df.format(new Date(nowDate.getTime() - Integer.valueOf(days) * 24 * 60 * 60 * 1000));
            log.info("当前需要给"+days+"天前的用户推送，推送任务id为:"+push.getId());

            JkGroupUser jkGroupUser = new JkGroupUser();
            jkGroupUser.setGroupId(push.getGroupId());
            jkGroupUser.setCreateTime(DateUtils.parseDate(format));
            List<JkGroupUser> jkGroupUsers = groupUserService.selectJkGroupUserList(jkGroupUser);
            jkGroupUsers.forEach(groupUser -> {
                userIds.add(groupUser.getUserId());
            });
        });
        if(userIds.size()==0){
            log.info("当日无推送任务->"+DateUtils.getDate());
            return;
        }
        Map<String, String> openIdAndUnionIdMap = weChatUtil.getOpenIdAndUnionIdMap();
        String gzhToken = weChatUtil.getGzhToken();
        List<JkUser> jkUsers = userService.selectJkUserByIds(userIds);
        for(JkUser user:jkUsers){
            String unionId = user.getUnionId();
            if(unionId==null||StringUtils.isEmpty(unionId)){
                log.info("用户unionId为空");
                continue;
            }
            //创建随访
            JkFllowup jkFllowup = new JkFllowup();
            jkFllowup.setUserId(user.getId());
            jkFllowup.setCreateTime(DateUtils.getNowDate());
            fllowupService.insertJkFllowup(jkFllowup);
            //站内推送
            JkFllowupMessage jkFllowupMessage = new JkFllowupMessage();
            jkFllowupMessage.setFllowupId(jkFllowup.getId());
            jkFllowupMessage.setUserId(user.getId());
            jkFllowupMessage.setIfRead(0);
            messageService.insertJkFllowupMessage(jkFllowupMessage);
//            try {
//                webSocketServer.sendMessageTo("refresh",user.getId().toString());
//            } catch (IOException e) {
//                throw new RuntimeException(e);
//            }

            String gzh_openId = openIdAndUnionIdMap.get(unionId);
            if(gzh_openId==null|| StringUtils.isEmpty(gzh_openId)){
                log.info("推送失败，未根据用户unionid："+unionId+"匹配到公众号openId");
            }else{
                //公众号推送
                sendMessage(gzh_openId,gzhToken,jkFllowup.getId(),jkFllowupMessage.getId());
            }
        };
    }
}
